package com.noteam.chinamapview;

import ohos.agp.components.Component;
import ohos.app.Context;
import ohos.multimodalinput.event.TouchEvent;

public class ScaleGestureDetector implements Component.TouchEventListener {
    private static final int INVALID_POINTER_INDEX = -1;
    private double fX, fY, sX, sY;
    private int mPointerIndex1, mPointerIndex2;
    private double mScale = 1;

    private OnScaleGestureListener mListener;

    private boolean isActive = false;

    public boolean isActive() {
        return isActive;
    }

    public void setActive(boolean active) {
        isActive = active;
    }

    public ScaleGestureDetector(Context context, OnScaleGestureListener listener) {
        mListener = listener;
        mPointerIndex1 = INVALID_POINTER_INDEX;
        mPointerIndex2 = INVALID_POINTER_INDEX;
    }

    public double getScale() {
        return mScale;
    }
    @Override
    public boolean onTouchEvent(Component component, TouchEvent event) {
        switch (event.getAction()) {
            case TouchEvent.PRIMARY_POINT_DOWN:
                sX = event.getPointerPosition(0).getX();
                sY = event.getPointerPosition(0).getY();
                mPointerIndex1 = event.getPointerId(0);
                break;
            case TouchEvent.OTHER_POINT_DOWN:
                fX = event.getPointerPosition(0).getX();
                fY = event.getPointerPosition(0).getY();
                mPointerIndex2 = event.getPointerId(event.getIndex());
                break;
            case TouchEvent.POINT_MOVE:
                if (mPointerIndex1 != INVALID_POINTER_INDEX && mPointerIndex2 != INVALID_POINTER_INDEX
                        && event.getPointerCount() > mPointerIndex2) {
                    isActive = true;
                    float nfX, nfY, nsX, nsY;
                    nsX = event.getPointerPosition(mPointerIndex1).getX();
                    nsY = event.getPointerPosition(mPointerIndex1).getY();
                    nfX = event.getPointerPosition(mPointerIndex2).getX();
                    nfY = event.getPointerPosition(mPointerIndex2).getY();
                    calculateScaleBetweenLines(nfX, nfY, nsX, nsY);
                    if (mListener != null) {
                        mListener.onScale(this);
                    }
                    fX = nfX;
                    fY = nfY;
                    sX = nsX;
                    sY = nsY;
                }
                break;
            case TouchEvent.PRIMARY_POINT_UP:
                mPointerIndex1 = INVALID_POINTER_INDEX;
                break;
            case TouchEvent.OTHER_POINT_UP:
                mPointerIndex2 = INVALID_POINTER_INDEX;
                break;
        }
        return true;
    }

    private void calculateScaleBetweenLines(double sx1, double sy1, double sx2, double sy2) {
        double absX = Math.abs(fX - sX);
        double absY = Math.abs(fY - sY);

        double absXt = Math.abs(sx1 - sx2);
        double absYt = Math.abs(sy1 - sy2);

        if (absX > absXt || absY > absYt) {
            if (mScale > 0.8f) {
                mScale = mScale - 0.05f;
            }
        }
        if (absX < absXt || absY < absYt) {
            mScale = mScale + 0.05f;
            if (mScale > 2){
                mScale = 2;
            }
        }
    }

    public interface OnScaleGestureListener {
        boolean onScale(ScaleGestureDetector scaleDetector);
        boolean onScaleBegin(ScaleGestureDetector scaleDetector);
        void onScaleEnd(ScaleGestureDetector scaleDetector);
    }
}
